#include "proto.h"
#include <signal.h>
#include <string.h>
#include <errno.h>
#include <poll.h>

#define MAX_CONNECT 1024
#define BUFFSIZE    128

static int max_two_number (int a, int b);
int main (void)
{
	int tcp_socket;
	int new_socket;
	struct sockaddr_in myaddr;
	fd_set rset, tmp_set;
	int max_fd, i = 0;
	int connected_arr[MAX_CONNECT] = {0};
	int cnt = 0;
	char buf[BUFFSIZE] = {0};
	struct sigaction act;
	int ret = 0;
	struct pollfd pfd[MAX_CONNECT] = {0};

	/*SIGCHLD*/
	act.sa_handler = SIG_DFL;
	act.sa_flags = SA_NOCLDWAIT;
	sigaction (SIGCHLD, &act, NULL);

	tcp_socket = socket (AF_INET, SOCK_STREAM, 0);
	if (-1 == tcp_socket) {
		perror ("socket()");
		exit (1);
	}
	//解决地址复用 
	int val = 1;
	if (-1 == setsockopt (tcp_socket, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)))
	{
		perror ("setsockopt()");
		goto ERROR;
	}
	
	myaddr.sin_family = AF_INET;
	myaddr.sin_port = htons (atoi(SERVER_PROT));
	myaddr.sin_addr.s_addr = INADDR_ANY;
	if (-1 == bind (tcp_socket, (struct sockaddr *)&myaddr, sizeof(myaddr))) {
		perror ("bind()");
		goto ERROR;
	}
	
	//设置监听
	if(-1 == listen (tcp_socket, 32)) {
		perror ("listen()");
		goto ERROR;
	}
	/*
	   需要监听客户端是否有请求到来
	   需要监听标准输入是否有数据, 如果有数据将发送给所有已连接的客户端 
	   需要监听所有已连接成功的客户端是否有数据到来
	 */
	pfd[0].fd = 0; 
	pfd[0].events = POLLIN; 
	pfd[1].fd = tcp_socket;
	pfd[1].events = POLLIN;
	max_fd = 2;
	
	while (1) {
		ret = poll (pfd, max_fd, -1);
		if (-1 == ret) {
			if (EINTR == errno) {
				continue;
			}
			perror ("poll()");
			goto ERROR;
		}
		//监听的事件发生了
		if (ret && (pfd[1].revents & POLLIN) > 0) {
			//有客户端的连接请求
			new_socket = accept (tcp_socket, NULL, NULL);
			if (-1 == new_socket) {
				perror ("accept ()");
				goto ERROR;
			}
			if (max_fd < MAX_CONNECT) {
				pfd[max_fd].fd = new_socket;
				pfd[max_fd].events = POLLIN;
				max_fd++;
			}
		} else if ((pfd[0].revents & POLLIN) && ret > 0) {
			bzero (buf, BUFFSIZE);
			cnt = read (0, buf, BUFFSIZE);
			if (-1 == cnt) {
				perror ("read");
				goto ERROR;
			}
			for (int j  = 2; j < max_fd; j++) {
				write (pfd[j].fd, buf, cnt);
			} 
		} else {
			//客户端有数据到来
			for (int j = 2; j < max_fd; j++) {
				if (pfd[j].revents & POLLIN) {
					bzero (buf, BUFFSIZE);
					cnt = read (pfd[j].fd, buf, BUFFSIZE);
					if (cnt == -1) {
						perror ("read()");
						goto ERROR;
					}
					if (cnt == 0) {
						//客户端断开连接
						memcpy (&(pfd[j].fd), &(pfd[j+1].fd), (max_fd - j -1)*sizeof(struct pollfd));
						j--;
						max_fd--;
					}
					puts (buf);
				}
			}
		}
	}

	close (tcp_socket);
	return 0;
ERROR:
	close (tcp_socket);
}

static int max_two_number (int a, int b)
{
	return a > b ? a : b;
}


